package com.blog.cmrpersonalblog.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.blog.cmrpersonalblog.dto.sensitiveword.requset.SensitiveWordBatchRequest;
import com.blog.cmrpersonalblog.dto.sensitiveword.requset.SensitiveWordCreateRequest;
import com.blog.cmrpersonalblog.dto.sensitiveword.requset.SensitiveWordQueryRequest;
import com.blog.cmrpersonalblog.dto.sensitiveword.respnose.SensitiveWordResponse;
import com.blog.cmrpersonalblog.entity.SensitiveWord;
import com.blog.cmrpersonalblog.mapper.SensitiveWordMapper;
import com.blog.cmrpersonalblog.service.SensitiveWordManagementService;
import com.blog.cmrpersonalblog.service.SensitiveWordService;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
// POI imports will be added when implementing Excel functionality
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.*;

/**
 * 敏感词管理服务实现类
 */
@Slf4j
@Service
public class SensitiveWordManagementServiceImpl implements SensitiveWordManagementService {

   @Resource
    private SensitiveWordMapper sensitiveWordMapper;

   @Resource
    private SensitiveWordService sensitiveWordService;

   @Resource
    private ObjectMapper objectMapper;

    @Override
    public IPage<SensitiveWordResponse> getSensitiveWordPage(SensitiveWordQueryRequest query) {
        log.info("分页查询敏感词列表，查询条件：{}", query);

        Page<SensitiveWordResponse> page = new Page<>(query.getCurrent(), query.getSize());
        IPage<SensitiveWordResponse> result = sensitiveWordMapper.selectSensitiveWordPage(page, query);

        // 处理标签字段
        result.getRecords().forEach(this::processTags);

        log.info("查询到敏感词{}条", result.getTotal());
        return result;
    }

    @Override
    public SensitiveWordResponse getSensitiveWordById(Long id) {
        log.info("根据ID获取敏感词详情，ID：{}", id);

        SensitiveWord sensitiveWord = sensitiveWordMapper.selectById(id);
        if (sensitiveWord == null) {
            throw new RuntimeException("敏感词不存在");
        }

        SensitiveWordResponse response = convertToResponse(sensitiveWord);
        processTags(response);

        return response;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createSensitiveWord(SensitiveWordCreateRequest request) {
        log.info("创建敏感词：{}", request.getWord());

        // 检查敏感词是否已存在
        if (sensitiveWordMapper.countByWord(request.getWord(), null) > 0) {
            throw new RuntimeException("敏感词已存在：" + request.getWord());
        }

        SensitiveWord sensitiveWord = new SensitiveWord();
        BeanUtils.copyProperties(request, sensitiveWord);

        // 处理标签
        if (request.getTags() != null && !request.getTags().isEmpty()) {
            try {
                sensitiveWord.setTags(objectMapper.writeValueAsString(request.getTags()));
            } catch (Exception e) {
                log.error("标签序列化失败", e);
                sensitiveWord.setTags("[]");
            }
        } else {
            sensitiveWord.setTags("[]");
        }

        // 设置创建信息
        Long currentUserId = StpUtil.getLoginIdAsLong();
        sensitiveWord.setCreateBy(currentUserId);
        sensitiveWord.setUpdateBy(currentUserId);
        sensitiveWord.setMatchCount(0L);

        int result = sensitiveWordMapper.insert(sensitiveWord);
        if (result > 0) {
            // 刷新敏感词缓存
            refreshSensitiveWordCache();
            log.info("敏感词创建成功，ID：{}", sensitiveWord.getId());
            return sensitiveWord.getId();
        } else {
            throw new RuntimeException("敏感词创建失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateSensitiveWord(Long id, SensitiveWordCreateRequest request) {
        log.info("更新敏感词，ID：{}，内容：{}", id, request.getWord());

        SensitiveWord existingSensitiveWord = sensitiveWordMapper.selectById(id);
        if (existingSensitiveWord == null) {
            throw new RuntimeException("敏感词不存在");
        }

        // 检查敏感词是否已存在（排除当前记录）
        if (sensitiveWordMapper.countByWord(request.getWord(), id) > 0) {
            throw new RuntimeException("敏感词已存在：" + request.getWord());
        }

        SensitiveWord sensitiveWord = new SensitiveWord();
        BeanUtils.copyProperties(request, sensitiveWord);
        sensitiveWord.setId(id);

        // 处理标签
        if (request.getTags() != null && !request.getTags().isEmpty()) {
            try {
                sensitiveWord.setTags(objectMapper.writeValueAsString(request.getTags()));
            } catch (Exception e) {
                log.error("标签序列化失败", e);
                sensitiveWord.setTags("[]");
            }
        } else {
            sensitiveWord.setTags("[]");
        }

        // 设置更新信息
        Long currentUserId = StpUtil.getLoginIdAsLong();
        sensitiveWord.setUpdateBy(currentUserId);
        sensitiveWord.setUpdateTime(LocalDateTime.now());

        int result = sensitiveWordMapper.updateById(sensitiveWord);
        if (result > 0) {
            // 刷新敏感词缓存
            refreshSensitiveWordCache();
            log.info("敏感词更新成功");
            return true;
        } else {
            throw new RuntimeException("敏感词更新失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteSensitiveWord(Long id) {
        log.info("删除敏感词，ID：{}", id);

        SensitiveWord sensitiveWord = sensitiveWordMapper.selectById(id);
        if (sensitiveWord == null) {
            throw new RuntimeException("敏感词不存在");
        }

        int result = sensitiveWordMapper.deleteById(id);
        if (result > 0) {
            // 刷新敏感词缓存
            refreshSensitiveWordCache();
            log.info("敏感词删除成功");
            return true;
        } else {
            throw new RuntimeException("敏感词删除失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> batchCreateSensitiveWords(SensitiveWordBatchRequest request) {
        log.info("批量创建敏感词，数量：{}", request.getWords().size());

        Map<String, Object> result = new HashMap<>();
        List<String> successWords = new ArrayList<>();
        List<String> failedWords = new ArrayList<>();
        List<String> existingWords = new ArrayList<>();

        Long currentUserId = StpUtil.getLoginIdAsLong();
        List<SensitiveWord> sensitiveWords = new ArrayList<>();

        for (String word : request.getWords()) {
            if (!StringUtils.hasText(word)) {
                continue;
            }

            word = word.trim();

            // 检查是否已存在
            if (sensitiveWordMapper.countByWord(word, null) > 0) {
                if (request.getOverwrite()) {
                    // 删除已存在的敏感词
                    SensitiveWord existing = sensitiveWordMapper.selectByWord(word);
                    if (existing != null) {
                        sensitiveWordMapper.deleteById(existing.getId());
                    }
                } else {
                    existingWords.add(word);
                    continue;
                }
            }

            SensitiveWord sensitiveWord = new SensitiveWord();
            sensitiveWord.setWord(word);
            sensitiveWord.setType(request.getType());
            sensitiveWord.setSeverity(request.getSeverity());
            sensitiveWord.setFilterMode(request.getFilterMode());
            sensitiveWord.setReplacement(request.getReplacement());
            sensitiveWord.setStatus(request.getStatus());
            sensitiveWord.setDescription(request.getDescription());
            sensitiveWord.setCreateBy(currentUserId);
            sensitiveWord.setUpdateBy(currentUserId);
            sensitiveWord.setMatchCount(0L);
            sensitiveWord.setCreateTime(LocalDateTime.now());
            sensitiveWord.setUpdateTime(LocalDateTime.now());

            // 处理标签
            if (request.getTags() != null && !request.getTags().isEmpty()) {
                try {
                    sensitiveWord.setTags(objectMapper.writeValueAsString(request.getTags()));
                } catch (Exception e) {
                    log.error("标签序列化失败", e);
                    sensitiveWord.setTags("[]");
                }
            } else {
                sensitiveWord.setTags("[]");
            }

            sensitiveWords.add(sensitiveWord);
            successWords.add(word);
        }

        // 批量插入
        if (!sensitiveWords.isEmpty()) {
            int insertCount = sensitiveWordMapper.batchInsert(sensitiveWords);
            if (insertCount != sensitiveWords.size()) {
                log.warn("批量插入敏感词部分失败，期望：{}，实际：{}", sensitiveWords.size(), insertCount);
            }

            // 刷新敏感词缓存
            refreshSensitiveWordCache();
        }

        result.put("successCount", successWords.size());
        result.put("failedCount", failedWords.size());
        result.put("existingCount", existingWords.size());
        result.put("successWords", successWords);
        result.put("failedWords", failedWords);
        result.put("existingWords", existingWords);

        log.info("批量创建敏感词完成，成功：{}，失败：{}，已存在：{}",
                successWords.size(), failedWords.size(), existingWords.size());

        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchUpdateStatus(List<Long> ids, Integer status) {
        log.info("批量更新敏感词状态，数量：{}，状态：{}", ids.size(), status);

        Long currentUserId = StpUtil.getLoginIdAsLong();
        int result = sensitiveWordMapper.batchUpdateStatus(ids, status, currentUserId);

        if (result > 0) {
            // 刷新敏感词缓存
            refreshSensitiveWordCache();
            log.info("批量更新敏感词状态成功，更新数量：{}", result);
            return true;
        } else {
            throw new RuntimeException("批量更新敏感词状态失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchDeleteSensitiveWords(List<Long> ids) {
        log.info("批量删除敏感词，数量：{}", ids.size());

        int result = sensitiveWordMapper.batchDelete(ids);

        if (result > 0) {
            // 刷新敏感词缓存
            refreshSensitiveWordCache();
            log.info("批量删除敏感词成功，删除数量：{}", result);
            return true;
        } else {
            throw new RuntimeException("批量删除敏感词失败");
        }
    }

    @Override
    public Map<String, Object> importSensitiveWords(MultipartFile file, String type, Integer severity,
                                                   String filterMode, Boolean overwrite) {
        // TODO: 实现Excel/CSV导入功能
        throw new RuntimeException("导入功能暂未实现");
    }

    @Override
    public void exportSensitiveWords(SensitiveWordQueryRequest query, HttpServletResponse response) {
        // TODO: 实现Excel导出功能
        throw new RuntimeException("导出功能暂未实现");
    }

    @Override
    public Map<String, Object> getSensitiveWordStatistics() {
        log.info("获取敏感词统计信息");
        return sensitiveWordMapper.selectStatistics();
    }

    @Override
    public Map<String, Long> getTypeDistribution() {
        log.info("获取敏感词类型分布");
        List<Map<String, Object>> distribution = sensitiveWordMapper.selectTypeDistribution();
        Map<String, Long> result = new HashMap<>();

        for (Map<String, Object> item : distribution) {
            String typeName = (String) item.get("typeName");
            Long count = ((Number) item.get("count")).longValue();
            result.put(typeName, count);
        }

        return result;
    }

    @Override
    public Map<String, Long> getSeverityDistribution() {
        log.info("获取敏感词严重程度分布");
        List<Map<String, Object>> distribution = sensitiveWordMapper.selectSeverityDistribution();
        Map<String, Long> result = new HashMap<>();

        for (Map<String, Object> item : distribution) {
            String severityName = (String) item.get("severityName");
            Long count = ((Number) item.get("count")).longValue();
            result.put(severityName, count);
        }

        return result;
    }

    @Override
    public Map<String, Long> getFilterModeDistribution() {
        log.info("获取敏感词过滤模式分布");
        List<Map<String, Object>> distribution = sensitiveWordMapper.selectFilterModeDistribution();
        Map<String, Long> result = new HashMap<>();

        for (Map<String, Object> item : distribution) {
            String filterModeName = (String) item.get("filterModeName");
            Long count = ((Number) item.get("count")).longValue();
            result.put(filterModeName, count);
        }

        return result;
    }

    @Override
    public List<SensitiveWordResponse> getPopularWords(Integer limit) {
        log.info("获取热门敏感词，限制数量：{}", limit);
        List<SensitiveWordResponse> result = sensitiveWordMapper.selectPopularWords(limit);
        result.forEach(this::processTags);
        return result;
    }

    @Override
    public Boolean refreshSensitiveWordCache() {
        log.info("刷新敏感词缓存");
        try {
            // 调用敏感词服务刷新缓存
            sensitiveWordService.refreshSensitiveWords();
            return true;
        } catch (Exception e) {
            log.error("刷新敏感词缓存失败", e);
            return false;
        }
    }

    @Override
    public Integer cleanExpiredStats(Integer days) {
        log.info("清理过期的匹配统计，保留天数：{}", days);
        return sensitiveWordMapper.cleanExpiredStats(days);
    }

    @Override
    public Map<String, Object> testSensitiveWordFilter(String content) {
        log.info("测试敏感词过滤，内容长度：{}", content != null ? content.length() : 0);

        Map<String, Object> result = new HashMap<>();

        if (!StringUtils.hasText(content)) {
            result.put("originalContent", content);
            result.put("filteredContent", content);
            result.put("hasSensitiveWords", false);
            result.put("sensitiveWords", new ArrayList<>());
            return result;
        }

        // 使用敏感词服务进行过滤
        String filteredContent = sensitiveWordService.filterSensitiveWords(content);
        boolean hasSensitiveWords = !content.equals(filteredContent);

        result.put("originalContent", content);
        result.put("filteredContent", filteredContent);
        result.put("hasSensitiveWords", hasSensitiveWords);

        // 如果有敏感词，获取检测到的敏感词列表
        if (hasSensitiveWords) {
            // TODO: 实现获取具体敏感词列表的功能
            result.put("sensitiveWords", new ArrayList<>());
        } else {
            result.put("sensitiveWords", new ArrayList<>());
        }

        return result;
    }

    /**
     * 处理标签字段
     */
    private void processTags(SensitiveWordResponse response) {
        if (StringUtils.hasText(response.getTags())) {
            try {
                List<String> tags = objectMapper.readValue(response.getTags(), new TypeReference<List<String>>() {});
                response.setTagList(tags);
            } catch (Exception e) {
                log.error("标签反序列化失败", e);
                response.setTagList(new ArrayList<>());
            }
        } else {
            response.setTagList(new ArrayList<>());
        }
    }

    /**
     * 转换为响应DTO
     */
    private SensitiveWordResponse convertToResponse(SensitiveWord sensitiveWord) {
        SensitiveWordResponse response = new SensitiveWordResponse();
        BeanUtils.copyProperties(sensitiveWord, response);
        return response;
    }
}